-#- title @plan.title
.page-header#plan-page-header{'v-if' => 'plan != null'}
  %span.plan_title{'v-text' => 'plan.title'}
  %span.plan_description{'v-text' => 'plan.description'}
  .plan-operations
    %i.icon-trash.has-tooltip.danger-opeartion{ title: '删除此计划项', 'data-toggle' => 'tooltip', 'data-placement' => 'right',
                                                'data-toggle' => 'modal', 'data-target' => '.delete_plan_modal' }
  .delete_plan_modal.modal.fade{'aria-hidden' => 'true', :role => 'dialog', :tabindex => '-1'}
    .modal-dialog
      .modal-content
        .modal-header
          %button.close{'data-dismiss' => 'modal', :type => 'button'}
            %span{'aria-hidden' => 'true'}
              %i.icon-remove
          %h4.modal-title
            确认删除 「{{plan.title}}」 ？
        .modal-body
          所属的任务组和任务都会被删除，且无法恢复，请谨慎操作。
        .modal-footer
          %button.btn.btn-default{'data-dismiss' => 'modal', :type => 'button'} 取消
          %button.btn.btn-danger{:type => 'button', 'v-on:click' => 'deletePlan'} 确认删除

.page-content#plan-page-content
  .row#list-content
    %draggable{':list' => "filterListData", ':options' => "{ animation: 150, handle: '.list-title-area' }", '@update' => 'updateListSort', class: 'draggable-class'}
      .col-md-3{'v-for' => 'list in filterListData', ':list_id' => 'list.id', ':key'=> 'list.id'}
        .panel.list-item{':class' => 'list.color_tag_class', ':value' => 'list.color_tag'}
          .panel-heading
            .list-title-area
              %span
                {{list.title}}
              .list-operations
                .list-limit-operations
                  %i.icon-pencil{title: '编辑', 'v-on:click' => 'editList()', 'data-toggle' => 'tooltip',
                                'data-placement' => 'left', onmouseover: "$(this).tooltip('show')"}
                  %i.icon-trash{title: '删除此任务组', 'v-on:click' => 'deleteListModal', 'data-toggle' => 'tooltip',
                                'data-placement' => 'left', onmouseover: "$(this).tooltip('show')"}
                %i.icon-plus.add-task-plus{title: '添加任务', 'v-on:click' => 'newTask', 'data-toggle' => 'tooltip',
                                           'data-placement' => 'left', onmouseover: "$(this).tooltip('show')"}
            .edit-list-area
              = render 'lists/edit_form'
            .delete_list_modal.modal.fade{'aria-hidden' => 'true', :role => 'dialog', :tabindex => '-1'}
              .modal-dialog
                .modal-content
                  .modal-header
                    %button.close{'data-dismiss' => 'modal', :type => 'button'}
                      %span{'aria-hidden' => 'true'}
                        %i.icon-remove
                    %h4.modal-title
                      确认删除 「{{list.title}}」 ？
                  .modal-body
                    所属的任务都会被删除，且无法恢复，请谨慎操作。
                  .modal-footer
                    %button.btn.btn-default{'data-dismiss' => 'modal', :type => 'button'} 取消
                    %button.btn.btn-danger{:type => 'button', 'v-on:click' => 'deleteList'} 确认删除

          .panel-body.task-lists
            .add-task-field
              = render 'tasks/form', type: 'new'
            %draggable{':list' => "list.tasks", ':options' => "{ animation: 150, group: 'tasks', ghostClass: 'on-holder', handle: '.task-item' }",
            '@end' => 'changeList', 'v-bind:class' => "{ 'empty-holder': list.tasks.length + list.over_tasks.length == 0}"}
              .task-field{'v-for' => 'task in list.tasks', ':task_id'=> 'task.id', ':key'=> 'task.id'}
                .update-task
                  = hidden_field_tag :task_value, '{{task.title}}', 'v-model' => 'task.title'
                  = render 'tasks/form', type: 'edit'
                .task-item{':class' => 'task.status_class'}
                  {{task.title}}
                .confirm-delete
                  %button.btn.btn-danger.btn-xs{'v-on:click' => 'removeTask(task.id)'}
                    确认删除
                  %button.btn.btn-default.btn-xs{'v-on:click' => 'removeConfirm'}
                    取消
                .task-operations
                  = hidden_field_tag :task_path, nil, 'v-model' => 'task.path'
                  .non-group{'v-show' => 'task.status == 1', 'v-on:click' => 'showEdit'}
                    %i.icon-pencil
                  .non-group
                    %i.icon-remove{'@click' => 'showConfirm'}
                  %button.btn.btn-primary.btn-xs{'v-on:click' => "updateTask('over')", 'v-show' => 'task.status == 1'}
                    over
                  %button.btn.btn-xs{'v-on:click' => "updateTask('reopen')", 'v-show' => 'task.status == 0'}
                    reopen
            %draggable{':list' => "list.over_tasks", ':options' => "{ animation: 150, group: 'over_tasks' }",
            '@end' => 'changeList'}
              .task-field{'v-for' => 'task in list.over_tasks', ':task_id'=> 'task.id', ':key'=> 'task.id'}
                .update-task
                  = hidden_field_tag :task_value, '{{task.title}}', 'v-model' => 'task.title'
                  = render 'tasks/form', type: 'edit'
                %span.task-item{':class' => 'task.status_class'}
                  {{task.title}}
                .confirm-delete
                  %button.btn.btn-danger.btn-xs{'v-on:click' => 'removeTask(task.id)'}
                    确认删除
                  %button.btn.btn-default.btn-xs{'v-on:click' => 'removeConfirm'}
                    取消
                .task-operations
                  = hidden_field_tag :task_path, nil, 'v-model' => 'task.path'
                  .non-group{'v-show' => 'task.status == 1', 'v-on:click' => 'showEdit'}
                    %i.icon-pencil
                  .non-group
                    %i.icon-remove{'@click' => 'showConfirm'}
                  %button.btn.btn-primary.btn-xs{'v-on:click' => "updateTask('over')", 'v-show' => 'task.status == 1'}
                    over
                  %button.btn.btn-default.btn-xs{'v-on:click' => "updateTask('reopen')", 'v-show' => 'task.status == 0'}
                    reopen
    .col-md-3#new_list_area{ 'v-show' => 'newListField' }
      #new_list_field
        = render 'lists/form'
      .add-list-buttons
        %button.btn.btn-sm.btn-default{ :type => 'button', 'v-on:click' => 'cancelList()' } 取消
        %button.btn.btn-sm.btn-primary{ :type => 'button', 'v-on:click' => 'addList()' } 提交
    .col-md-3#new-list-button{ 'v-show' => '!!!newListField' }
      %a{'v-on:click' => 'newList()'}
        .plan-list-add
          %i.icon-plus
          添加一个任务组

:javascript
  var PlanUrl = '/p/' + gon.plan_ident + '.json'
  var lists_tasks = new Vue({
    el: '#app',
    data: {
      plan: {
        title: '',
        description: '',
        new_list_path: '',
        lists: [{
          id: '',
          title: '',
          color_tag: '',
          color_tag_class: '',
          path:'',
          tasks: [{
            id: '',
            path: '',
            title: '',
            status: '',
            status_class: ''
          }],
          over_tasks: [{
            id: '',
            path: '',
            title: '',
            status: '',
            status_class: ''
          }]
        }]
      },
      list: {
        title: '',
        color_tag: 0
      },
      colorFilter: '',
      newListField: false
    },
    created: function () {
      this.fetchData()
    },
    beforeUpdate: function () {
      $('.overlay-loading').hide()
    },
    computed: {
      filterListData: function() {
        var data = this.plan.lists
        var filterArray = []
        var filterStr = this.colorFilter
        if ( filterStr == ''){
          return data
        }else{
          for (var i = 0; i < data.length; i++){
            if ( data[i].color_tag == filterStr ){
              filterArray.push(data[i])
            }
          }
          return filterArray
        }
      }
    },
    methods: {
      fetchData: function () {
        var xhr = new XMLHttpRequest()
        var self = this
        xhr.open('GET', PlanUrl)
        xhr.onload = function () {
          result = JSON.parse(xhr.responseText)
          if (result.status == 'failed') {
            notifyTop(result.alert + '，正在返回首页...', 'danger')
            setTimeout(function(){window.location="/";}, 2000);
          } else {
            self.plan = result
          }
        }
        xhr.send()
      },
      newList: function () {
        this.newListField = true
      },
      cancelList: function () {
        this.newListField = false
      },
      editList: function () {
        $(event.currentTarget).closest('.list-title-area').hide()
        $(event.currentTarget).closest('.panel-heading').find('.edit-list-area').show()
      },
      cancelEditList: function () {
        $(event.currentTarget).closest('.edit-list-area').hide()
        $(event.currentTarget).closest('.panel-heading').find('.list-title-area').show()
      },
      newTask: function () {
        $(event.currentTarget).closest('.panel').find('.add-task-field').show()
      },
      cancelTask: function () {
        $(event.currentTarget).closest('.add-task-field').hide()
      },
      showConfirm: function() {
        $(event.currentTarget).closest('.task-operations').hide()
        $(event.currentTarget).closest('.task-field').find('.confirm-delete').show()
      },
      removeConfirm: function() {
        $(event.currentTarget).closest('.task-field').find('.task-operations').show()
        $(event.currentTarget).closest('.confirm-delete').hide()
      },
      showEdit: function() {
        task = $(event.currentTarget).closest('.task-field').find('#task_value').val()
        $(event.currentTarget).closest('.task-field').find('.task-item, .task-operations').hide()
        $(event.currentTarget).closest('.task-field').find('.update-task').show()
        $(event.currentTarget).closest('.task-field').find('#task_title').val(task)
      },
      removeEdit: function() {
        $(event.currentTarget).closest('.update-task').hide()
        $(event.currentTarget).closest('.task-field').find('.task-item, .task-operations').show()
      },
      selectColor: function (color, action){
        var fieldBorder;
        if (action == 'new') {
          fieldBorder = $('#new_list_field')
        }else{
          evt = $(event.currentTarget)
          fieldBorder = evt.closest('.list-item')
          evt.closest('.list-item').attr('value', evt.attr('value'))
        }
        fieldBorder.css({'border-top-color': color})
      },
      deletePlan: function() {
        var xhr = new XMLHttpRequest()
        xhr.open("DELETE", PlanUrl)
        xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded")
        xhr.onload = function () {
          result = JSON.parse(xhr.responseText)
          $('.delete_plan_modal').modal('hide')
          notifyTop(result.message)
          setTimeout(function(){window.location="/";}, 2000);
        }
        xhr.send()
      },
      deleteListModal: function() {
        $(event.currentTarget).closest('.panel-heading').find('.delete_list_modal').modal('show')
      },
      deleteList: function() {
        var xhr = new XMLHttpRequest()
        var listPath = $(event.currentTarget).closest('.panel').find('#new_task_path').val()
        var data = this.plan.lists
        xhr.open("DELETE", listPath + '.json')
        xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded")
        xhr.onload = function () {
          result = JSON.parse(xhr.responseText)
          for (var i = 0; i < data.length; i++){
            if ( data[i].path == listPath ){
              data.splice(i, 1)
            }
          }
          notifyTop(result.message)
        }
        xhr.send()
        $(event.currentTarget).closest('.delete_list_modal').modal('hide')
      },
      removeTask: function(id) {
        var $currentTarget = $(event.currentTarget)
        var data = this.plan.lists
        var path = $currentTarget.closest('.task-field').find('#task_path').val()
        var listId = $(event.currentTarget).closest('.col-md-3').attr('list_id')
        list = handleItemById(data, listId, 'get')
        this.$http.delete(path).then(
          response => {
            handleItemById(list.tasks, id, 'remove')
            handleItemById(list.over_tasks, id, 'remove')
            $currentTarget.closest('.task-field').find('.task-operations').show()
            $currentTarget.closest('.confirm-delete').hide()
            notifyTop('任务删除成功!')
          },
          response => {
            notifyTop(result.alert)
          }
        )
      },
      updateTask: function(item) {
        var xhr = new XMLHttpRequest()
        var sortXhr = new XMLHttpRequest()
        var data = this.plan.lists
        var $currentTarget = $(event.currentTarget)
        var listId = $(event.currentTarget).closest('.col-md-3').attr('list_id')
        var path = $currentTarget.closest('.task-field').find('#task_path').val()
        var task_value = $currentTarget.closest('#edit_task').find('#task_title').val()
        var list = handleItemById(data, listId, 'get')
        var task = false
        xhr.open("PUT", path + '.json')
        xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded")
        xhr.onload = function () {
          result = JSON.parse(xhr.responseText)
          if (result.status == 'failed') {
            notifyTop(result.message, 'danger')
          } else {
            task = handleItemById(list.tasks, result.id, 'get')
            if (task == false){
              task = handleItemById(list.over_tasks, result.id, 'get')
            }
            if (item == 'over') {
              list.tasks.splice($.inArray(task,list.tasks), 1)
              list.over_tasks.unshift(result)
            } else if ((item == 'reopen')) {
              list.over_tasks.splice($.inArray(task,list.over_tasks), 1)
              list.tasks.unshift(result)
            } else {
              task.title = task_value
              $currentTarget.closest('.update-task').hide()
              $currentTarget.closest('.task-field').find('.task-item, .task-operations').show()
            }
            notifyTop('任务更新成功 !')
            if (item != 'edit'){
              sort = $.merge(list.tasks.map(function(item) {return item.id}), list.over_tasks.map(function(item) {return item.id}))
              sortXhr.open("PUT", list.path + '/tasks/update_sort.json')
              sortXhr.setRequestHeader("Content-type","application/x-www-form-urlencoded")
              sortXhr.send('sort=' + sort)
            }
          }
        }
        if (item == 'over') {
          urlParams = 'task[status]=0'
        } else if (item == 'reopen') {
          urlParams = 'task[status]=1'
        } else {
          urlParams = 'task[title]=' + task_value
        }
        xhr.send(urlParams)
      },
      submitEditList: function(id) {
        var xhr = new XMLHttpRequest()
        evt = $(event.currentTarget)
        var titleInput = evt.closest('#edit_list').find('#list_title').val()
        var self = this
        if (titleInput == ''){
          return notifyTop('任务组名称不能为空', 'warning');
        }
        var colorTag = evt.closest('.list-item').attr('value')
        var url = evt.closest('.panel').find('#new_task_path').val() + '.json'
        xhr.open("PUT", url)
        xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded")
        xhr.onload = function () {
          result = JSON.parse(xhr.responseText)
          evt.closest('.edit-list-area').hide()
          evt.closest('.panel-heading').find('.list-title-area').show()
          notifyTop('任务组修改成功!')
          for (var i = 0; i < self.plan.lists.length; i++){
            if ( self.plan.lists[i].id == id ){
              self.plan.lists[i].title = result.title
              self.plan.lists[i].color_tag = result.color_tag
              self.plan.lists[i].color_tag_class = result.color_tag_class
            }
          }
        }
        xhr.send( "list[title]="+ titleInput + "&list[color_tag]=" + colorTag )
      },
      addList: function () {
        var xhr = new XMLHttpRequest()
        var self = this
        var addListUrl = this.plan.new_list_path
        if (this.list.title == ''){
          $('#list_title').css({'border-color':'#d9534f'})
          return notifyTop('列表名称不能为空', 'warning');
        }
        xhr.open("POST", addListUrl)
        xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded")
        xhr.onload = function () {
          result = JSON.parse(xhr.responseText)
          self.plan.lists.push(result)
          self.newListField = false
          notifyTop('列表 ' + result.title + ' 创建成功!')
          self.list.title = ''
          $('#list_title').css({'border-color':'#ccc'})
        }
        xhr.send( "list[title]="+ this.list.title + "&list[color_tag]=" + this.list.color_tag )
      },
      addTask: function () {
        var xhr = new XMLHttpRequest()
        var self = this
        var listPath = $(event.currentTarget).closest('#new_task').find('#new_task_path').val()
        var listId = $(event.currentTarget).closest('.col-md-3').attr('list_id')
        var addTaskUrl = listPath + '/tasks.json'
        var taskInput = $(event.currentTarget).closest('#new_task').find('#task_title')
        var task = taskInput.val()
        var data = self.plan.lists
        var list = handleItemById(data, listId, 'get')
        if (task == ''){
          taskInput.css({'border-color':'#d9534f'})
          return notifyTop('任务名称不能为空', 'warning');
        } else if (!list) {
          return notifyTop('列表不存在', 'warning');
        }
        xhr.open("POST", addTaskUrl)
        xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded")
        xhr.onload = function () {
          result = JSON.parse(xhr.responseText)
          list.tasks.unshift(result)
          notifyTop('任务 ' + result.title + ' 创建成功!')
          taskInput.val('')
        }
        xhr.send( "task[title]="+ task )
      },
      updateListSort: function() {
        var updateListSortUrl = '/p/' + gon.plan_ident + '/lists/update_sort.json'
        var xhr = new XMLHttpRequest()
        var sort = this.plan.lists.map(function(item) {return item.id})
        xhr.open("PUT", updateListSortUrl)
        xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded")
        xhr.send( "sort=" + sort )
      },
      changeList: function(evt) {
        var toList = false
        var fromList = false
        var data = this.plan.lists
        var toListId = $(evt.to).closest('.col-md-3').attr('list_id')
        var fromListId = $(evt.from).closest('.col-md-3').attr('list_id')
        var taskId = $(evt.item).attr('task_id')
        toList = handleItemById(data, toListId, 'get')
        toSort = $.merge(toList.tasks.map(function(item) {return item.id}), toList.over_tasks.map(function(item) {return item.id}))
        params = 'to_sort=' + toSort + '&to_list_id=' + toListId + '&task_id=' + taskId
        if ( toListId != fromListId ){
          fromList = handleItemById(data, fromListId, 'get')
          fromSort = $.merge(fromList.tasks.map(function(item) {return item.id}), fromList.over_tasks.map(function(item) {return item.id}))
          params += '&from_sort=' + fromSort + '&from_list_id=' + fromListId
        }
        var updateTaskSortUrl = '/p/' + gon.plan_ident + '/update_task_sort.json'
        var xhr = new XMLHttpRequest()
        xhr.open("PUT", updateTaskSortUrl)
        xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded")
        xhr.send( params )
      }
    }
  })
  function handleItemById(data, id, action) {
    var item = false
    for (var i = 0; i < data.length; i++){
      if ( data[i].id == id ){
        if (action == 'get'){
          item = data[i]
        } else if (action == 'remove'){
          data.splice(i, 1)
        }
      }
    }
    return item
  }
